package ar.edu.itba.it.raytracer.scene

import scala.math.{ pow, min }
import ar.edu.itba.it.raytracer.engine.{ Ray, Vector, Color }
import scala.math.sqrt
import scala.collection.mutable.ListBuffer
import Geom.eps
import ar.edu.itba.it.raytracer.engine.Vector._
import scala.math.abs

case class AABB(v1: Vector, size: Double) extends Geom {
  lazy val v2 = v1 + Vector(size, size, size)

  def normal(poi: Vector, ray: Ray): Vector = {
    val directions = Map(
      abs(poi.x - v1.x) -> left, abs(poi.x - v2.x) -> right,
      abs(poi.y - v1.y) -> down, abs(poi.y - v2.y) -> up,
      abs(poi.z - v1.z) -> behind, abs(poi.z - v2.z) -> front)

    directions(directions.keys.min)
  }

  def intersect(ray: Ray): Option[Vector] = { 
    val ts = new ListBuffer[Double]
    if (ray.direction.x != 0) {
      val rc = 1 / ray.direction.x
      ts += (v1.x - ray.origin.x) * rc
      ts += (v2.x - ray.origin.x) * rc
    }
    if (ray.direction.y != 0) {
      val rc = 1 / ray.direction.y
      ts += (v1.y - ray.origin.y) * rc
      ts += (v2.y - ray.origin.y) * rc
    }
    if (ray.direction.z != 0) {
      val rc = 1 / ray.direction.z
      ts += (v1.z - ray.origin.z) * rc
      ts += (v2.z - ray.origin.z) * rc
    }

    ts.filter({t =>
        val poi = ray(t)
        poi.x > v1.x - eps && poi.x <= v2.x + eps && poi.y > v1.y - eps && poi.y <= v2.y + eps && poi.z > v1.z - eps && poi.z <= v2.z + eps
    }).sorted.firstOption.map(ray(_))
  }
}